/*

分支切换
针对 data.ok ? data.text : 'not'
data.ok从true变为false时，data.text中不应该遗留有effect
需对遗留的副作用函数进行清理

把收集有effect的set存在effect.deps里
执行effect之前，先对effect.deps进行清理
在get的时候重新进行依赖收集

死循环问题：
修改data.ok，触发trigger（forEach循环执行effect）
执行effect，清空deps，触发get，track，重新依赖收集

解决：触发trigger（forEach循环执行effect），使用一个新的set

*/

let data = {
    text: "init",
    color: "white",
    ok: true,
}
const weakMap = new WeakMap()
let activeEffect

data = new Proxy(data, {
    get(target, prop) {
        track(target, prop)
        return Reflect.get(...arguments)
    },
    set(target, prop, val) {
        Reflect.set(...arguments)
        trigger(target, prop)
    }
})

function track(target, prop) {
    if (!activeEffect) return
    if (!weakMap.has(target)) weakMap.set(target, new Map())
    const map = weakMap.get(target)
    if (!map.has(prop)) map.set(prop, new Set())
    const set = map.get(prop)
    set.add(activeEffect)
    activeEffect.deps.push(set)
}

function trigger(target, prop) {
    const set = weakMap.get(target)?.get(prop)
    if (!set) return
    const newSet = new Set()
    set.forEach(fn => newSet.add(fn));
    newSet.forEach(fn => fn())
}

function effect(fn) {
    const wrapper = function () {
        wrapper.deps.forEach(set => {
            set.delete(activeEffect)
        })
        activeEffect = wrapper
        fn()
    }
    wrapper.deps = []
    wrapper()
}

function fn() {
    document.body.innerText = data.ok ? data.text : 'not'
}

function fn2() {
    document.body.style.backgroundColor = data.color
}

effect(fn)
setTimeout(() => {
    data.ok = false
}, 1000)
// console.log(weakMap);

